<?php

namespace App\Services\Utils;

use Illuminate\Support\Facades\DB;
use Monolog\Formatter\LineFormatter;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

class BusLogService
{
    protected static $levels = [
        'debug' => Logger::DEBUG,
        'info' => Logger::INFO,
        'notice' => Logger::NOTICE,
        'warning' => Logger::WARNING,
        'error' => Logger::ERROR,
        'critical' => Logger::CRITICAL,
        'alert' => Logger::ALERT,
        'emergency' => Logger::EMERGENCY,
    ];

    private static function writeLog($level = 'info', $message = '', $data = [], $dirName = 'logs')
    {
        $log = new Logger(env('APP_NAME'));
        $path = storage_path($dirName) . DIRECTORY_SEPARATOR . date('Ym');
        self::mkDirs($path);
        $fileName = $path . DIRECTORY_SEPARATOR . date('Ymd') . '.log';
        if (gettype($data) != 'array') {
            $message .= "：" . $data;
            $data = [];
        }
        $stream = new StreamHandler($fileName, self::$levels[$level]);
        $dateFormat = "Y-m-d H:i:s";
        $output = "%datetime% -- %channel%.%level_name% \n【%message%】 \n ======================== \n %context%\n\n";
        $formatter = new LineFormatter($output, $dateFormat);
        $stream->setFormatter($formatter);
        $log->pushHandler($stream);
        $log->log($level, $message, $data);
    }

    /**
     * 给日志文件夹权限
     * @param $dir
     * @param int $mode
     * @return bool
     */
    public static function mkDirs($dir, $mode = 0777)
    {
        if (is_dir($dir) || @mkdir($dir, $mode)) {
            return TRUE;
        }
        if (!self::mkdirs(dirname($dir), $mode)) {
            return FALSE;
        }
        return @mkdir($dir, $mode);
    }

    /**
     * 记录 sql执行
     * @param string $file_name
     * @param bool $is_date
     */
    public static function sql($fileName = 'sql', $is_date = false)
    {
        DB::listen(function ($sql) use ($fileName, $is_date) {
            foreach ($sql->bindings as $i => $binding) {
                if ($binding instanceof \DateTime) {
                    $sql->bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
                } else {
                    if (is_string($binding)) {
                        $sql->bindings[$i] = "'$binding'";
                    }
                }
            }
            $query = str_replace(array('%', '?'), array('%%', '%s'), $sql->sql);
            $query = vsprintf($query, $sql->bindings);
            BusLogService::info('sql脚本:', $query, 'sqllogs');
        });
    }

    public static function __callStatic($name, $arguments)
    {
        return self::writeLog($name, ...$arguments);
    }
}
